package com.m3958.firstgwt.server.ftpserver;

import java.io.File;

import org.apache.ftpserver.filesystem.nativefs.NativeFileSystemFactory;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.assistedinject.Assisted;
import com.m3958.firstgwt.server.dao.WebSiteDao;
import com.m3958.firstgwt.server.module.AssistedObjectFactory;

/**
 * 
 * @author jianglibo
 * copy from NativeFileSystemView
 *
 */

public class MyFileSystemView implements FileSystemView{
	
    private final Logger LOG = LoggerFactory
    .getLogger(MyFileSystemView.class);
    
    @Inject
    private AssistedObjectFactory aof;
    
    @Inject
    private Injector injector;


    // the root directory will always end with '/'.
    private String rootDir;

    // the first and the last character will always be '/'
    // It is always with respect to the root directory.
    private String currDir;

    private User user;

    // private boolean writePermission;

    private boolean caseInsensitive = false;

    /**
     * Constructor - internal do not use directly, use {@link NativeFileSystemFactory} instead
     */
    protected MyFileSystemView(User user) throws FtpException {
        this(user, false);
    }

    /**
     * Constructor - internal do not use directly, use {@link NativeFileSystemFactory} instead
     */
    @Inject
    public MyFileSystemView(@Assisted User user,@Assisted boolean caseInsensitive)
            throws FtpException {
        if (user == null) {
            throw new IllegalArgumentException("user can not be null");
        }
        if (user.getHomeDirectory() == null) {
            throw new IllegalArgumentException(
                    "User home directory can not be null");
        }

        this.caseInsensitive = caseInsensitive;

        // add last '/' if necessary
        String rootDir = user.getHomeDirectory();
        rootDir = MyNativeFtpFile.normalizeSeparateChar(rootDir);
        if (!rootDir.endsWith("/")) {
            rootDir += '/';
        }
        
        LOG.debug("Native filesystem view created for user \"{}\" with root \"{}\"", user.getName(), rootDir);
        
        this.rootDir = rootDir;

        this.user = user;

        currDir = "/";
    }

    /**
     * Get the user home directory. It would be the file system root for the
     * user.
     */
    public FtpFile getHomeDirectory() {
//        return new MyNativeFtpFile("/", new File(rootDir), user);
        return aof.getMyNativeFtpFile("/", new File(rootDir), user);
    }

    /**
     * Get the current directory.
     */
    public FtpFile getWorkingDirectory() {
        FtpFile fileObj = null;
        if (currDir.equals("/")) {
//            fileObj = new MyNativeFtpFile("/", new File(rootDir), user);
            fileObj = aof.getMyNativeFtpFile("/", new File(rootDir), user);
        } else {
            File file = new File(rootDir, currDir.substring(1));
//            fileObj = new MyNativeFtpFile(currDir, file, user);
            fileObj = aof.getMyNativeFtpFile(currDir, file, user);
        }
        return fileObj;
    }

    /**
     * Get file object.
     */
    public FtpFile getFile(String file) {

        // get actual file object
    	
        String physicalName = MyNativeFtpFile.getPhysicalName(rootDir,
                currDir, file, caseInsensitive);
        File fileObj = new File(physicalName);
        // strip the root directory and return
        String userFileName = physicalName.substring(rootDir.length() - 1);
//        return new MyNativeFtpFile(userFileName, fileObj, user);
        return aof.getMyNativeFtpFile(userFileName, fileObj, user);
    }

    /**
     * Change directory.
     */
    public boolean changeWorkingDirectory(String dir) {
        if("/".equals(currDir) && dir.matches("^\\d+,[^/]+$")){
        	dir = dir.split(",")[0];
        }

        // not a directory - return false
        dir = MyNativeFtpFile.getPhysicalName(rootDir, currDir, dir,
                caseInsensitive);
        //如果当前目录是/，并且dir match "^\\d+,[^/]+$"

        File dirObj = new File(dir);
        if (!dirObj.isDirectory()) {
            return false;
        }

        // strip user root and add last '/' if necessary
        dir = dir.substring(rootDir.length() - 1);
        String[] ds = dir.split("/");//這裡的dir總是/開頭減去rootdir。
        if(ds.length > 1){
        	WebSiteDao wdao = injector.getInstance(WebSiteDao.class);
        	if(!wdao.hasFtpPermission(user.getName(), ds[1])){
        		dir = "/";
        	}
        }
        
        if (dir.charAt(dir.length() - 1) != '/') {
            dir = dir + '/';
        }

        currDir = dir;
        return true;
    }

    /**
     * Is the file content random accessible?
     */
    public boolean isRandomAccessible() {
        return true;
    }

    /**
     * Dispose file system view - does nothing.
     */
    public void dispose() {
    }

}
